#include <iostream>
#include <string>
#include <unordered_map>
#include <stdlib.h>
#include <unistd.h>
#include "Util.hpp"
#include "Protocol.h"

using namespace std;

bool GetParam(string &out)
{
    char *env1 = getenv("METHOD");
    if (env1 == nullptr)
    {
        return false;
    }
    string method = env1;

    // cerr << "[CGI program] request_method: " << method << endl;
    if (method == "GET")
    {
        char *env2 = getenv("QUERY_STRING");
        if (env2 == nullptr)
        {
            return false;
        }
        out = env2;

        // cerr << "[CGI program] query_string: " << queryStr << endl;
    }
    else if (method == "POST")
    {
        char *env3 = getenv("CONTENT_LENGTH");
        if (env3 == nullptr)
        {
            return false;
        }
        size_t length = stoul(env3);

        // cerr << "[CGI program] content_length: " << length << endl;
        // string content;
        char buffer[1024];
        size_t total = 0;
        while (total < length)
        {
            int n = read(0, buffer, sizeof(buffer));
            if (n > 0)
            {
                out.append(buffer, n);
                total += n;
            }
            else
            {
                break;
            }
        }
        if (total < length)
            return false;
        // cerr << "[CGI program] content: " << content << endl;
    }
    else
    {
        return false;
    }
    return true;
}

bool AnalyseParam(const string &in, unordered_map<string, string> &out)
{
    size_t left = 0;
    size_t right = 0;
    size_t len = 0;
    string item, k, v;

    while (right != string::npos)
    {
        right = in.find('&', left);
        len = right == string::npos ? string::npos : right - left;
        item = in.substr(left, len);
        if (!Util::CutString(item, k, v, "="))
            return false;
        out.insert(make_pair(k, v));
        left = right + 1;
    }
    return true;
}

int main()
{
    string paramStr;
    if (!GetParam(paramStr))
    {
        return CGI_BADREQUEST;
    }

    unordered_map<string, string> paramMap;
    if (!AnalyseParam(paramStr, paramMap))
    {
        return CGI_BADREQUEST;
    }

    // 处理数据
    if (!paramMap.count("x") || !paramMap.count("y"))
    {
        return CGI_BADREQUEST;
    }
    int x = stoi(paramMap["x"]);
    int y = stoi(paramMap["y"]);

    // 返回结果
    cout << "<html>" << endl;
    cout << "<head><meta charset=\"utf-8\"><title>计算结果</title></head>" << endl;
    cout << "<body>" << endl;
    char buffer[128];
    snprintf(buffer, sizeof(buffer)-1, "<h3>%d + %d = %d</h3>", x, y, x+y);
    cout << buffer << endl;
    snprintf(buffer, sizeof(buffer)-1, "<h3>%d - %d = %d</h3>", x, y, x-y);
    cout << buffer << endl;
    snprintf(buffer, sizeof(buffer)-1, "<h3>%d * %d = %d</h3>", x, y, x*y);
    cout << buffer << endl;
    snprintf(buffer, sizeof(buffer)-1, "<h3>%d / %d = %d</h3>", x, y, x/y);
    cout << buffer << endl;
    cout << "</body>" << endl;
    cout << "</html>" << endl;

    return CGI_OK;
}